namespace YM {
    export class ResInfo {
        name: string;
        path: string;
        type: new()=>any;
        res:any;
        constructor(name:string,path:string,type:new()=>any,res){
            this.name=name;
            this.path=path;
            this.type=type;
            this.res=res;
        }
    }
    
    export class Resource {
        private resDict: Map<{ new() }, Map<string, ResInfo>> = new Map<{ new()}, Map<string, ResInfo>>();
        public load(url: string | string[] | any[], complete?: laya.utils.Handler | null, progress?: laya.utils.Handler | null, type?: string | null, priority?: number, cache?: boolean, group?: string | null, ignoreCache?: boolean, useWorkerLoader?: boolean): Laya.LoaderManager {
            return Laya.loader.load(url, complete, progress, type, priority, cache, group, ignoreCache, useWorkerLoader);
        }
        public create(url:any,complete?:laya.utils.Handler|null,progress?:laya.utils.Handler|null,type?:string|null,constructParams?:any[]|null,propertyParams?:any,priority?:number,cache?:boolean):void{
            Laya.loader.create(url,complete,progress,type,constructParams,propertyParams,priority,cache);
        }
        
        public async loadAsync<T>(url: string,progressCallback?: laya.utils.Handler) {
            return new Promise<T>((resolve,reject) => {

                let res=Laya.loader.getRes(url);
                if(res){
                    resolve(res);
                    return;
                }
                this.load(url,Laya.Handler.create(this,()=>{

                    let res=Laya.loader.getRes(url);
                    if(!res){
                        reject();
                        throw new Error(url+"：为空！");
                    }
                    this.addResInfo(res,url);
                    resolve(res);
                }),progressCallback);
            });
        }
        public async loadArrAsync(urls: any[],progressCallback?: laya.utils.Handler) {
            return new Promise<Array<any>>((resolve,reject) => {
                Laya.loader.load(urls,Laya.Handler.create(this,(tttt)=>{
                    let resArr:Array<any>=new Array<any>();
                    urls.forEach((url:any,index:number)=>{
                        let pathUrl;
                        if(typeof url=="string"){
                            pathUrl=url;
                        }
                        else{
                            pathUrl=url.url;
                           
                        }

                        let res=Laya.loader.getRes(pathUrl);
                        if(!res){
                            reject();
                            throw new Error(pathUrl+"：为空！");
                        }
                        resArr.push(res);
                        this.addResInfo(res,pathUrl);
                    });
                    resolve(resArr);
                }),progressCallback);
            });
        }
        public async createAsync<T>(url: any, progressCallback?: laya.utils.Handler) {
            return new Promise<T>((resolve,reject) => {
                let res=Laya.loader.getRes(url);
                if(res){
                    resolve(res);
                    return;
                }
                this.create(url,Laya.Handler.create(this,()=>{
                    let res=Laya.loader.getRes(url);
                    if(!res){
                        reject();
                        throw new Error(url+"：为空！");
                    }
                    this.addResInfo(res,url);
                    resolve(res);
                }),progressCallback);
            });
        }
        public async createArrAsync<T>(urls: any[],progressCallback?: laya.utils.Handler) {
            return new Promise<T[]>((resolve,reject) => {
                this.create(urls,Laya.Handler.create(this,()=>{
                    let resArr:Array<any>=new Array<any>();
                    urls.forEach((url,index:number)=>{
                        let res=Laya.loader.getRes(url.url);
                        if(!res){
                            reject();
                            throw new Error(url.url+"：为空！");
                        }
                        resArr.push(res);
                        this.addResInfo(res,url.url);
                    });
                    resolve(resArr);
                }),progressCallback);
            });
        }
        public getRes<T>(type: { new(): T }, name: string): T {
            let resDic = this.resDict.get(type);
            if (resDic == null) {
                return null;
            }
            let resInfo = resDic.get(name);
            if (resInfo == null) {
                return null;
            }

            return resInfo.res as T;
        }
        public getResByPath<T extends laya.events.EventDispatcher>(url: string) {
            return Laya.loader.getRes(url) as T;
        }
        public setRes<T>(type:new()=>T,res,resName:string,path?:string){
            let resDic = this.resDict.get(type);
            if (resDic == null) {
                resDic=new Map<string,ResInfo>();
                this.resDict.set(type,resDic);
            }
            let resInfo=new ResInfo(resName,path,type,res);
            resDic.set(resName,resInfo);
        }
        public release(url:string):void{
            Laya.loader.clearRes(url);
        }
        private addResInfo(res, path: string) {
            let fileName=path.substring(path.lastIndexOf("/")+1);
            fileName=fileName.substring(0,fileName.lastIndexOf("."));
            let resInfo = new ResInfo(fileName,path,(<any>res).__proto__.constructor,res);   
            let dic = this.resDict.get(resInfo.type);
            if (dic == null) {
                dic = new Map<string, ResInfo>();
                this.resDict.set(resInfo.type, dic);
            }
            dic.set(resInfo.name, resInfo);
        }
    }
}